In [ ]:
%matplotlib inline

In [ ]:
import matplotlib.pyplot as plt
import numpy as np
import sympy as sym

import pypwt
import solowpy

2. Computing the steady state

Traditionally, most analysis of the Solow model focuses almost excusively on the long run steady state of the model. Recall that the steady state of the Solow model is the value of capital stock (per unit effective labor) that solves

$$ 0 = sf(k^*) - (g + n + \delta)k^*. \tag{2.0.1} $$

In words: in the long-run, capital stock (per unit effective labor) converges to the value that balances actual investment, $sf(k)$, with effective depreciation, $(g + n + \delta)$. Given the assumption made about the aggregate production technology, $F$, and its intensive form, $f$, there is always a unique value $k^* >0$ satisfying equation 2.0.1.


In [ ]:
# define model parameters
ces_params = {'A0': 1.0, 'L0': 1.0, 'g': 0.02, 'n': 0.03, 's': 0.15,
              'delta': 0.05, 'alpha': 0.33, 'sigma': 0.95}

# create an instance of the solow.Model class
ces_model = solowpy.CESModel(params=ces_params)

2.1 Analytic results

For many (all?) of the commonly used functional forms for $F$ one can easily derive a closed-form expression for the steady state value of capital stock (per unit effective labor). For example, assuming $F$ is constant elasticity of substitution (CES), the analytical solution for $k^*$ is

$$ k^* = \left[\frac{1-\alpha}{\bigg(\frac{g+n+\delta}{s}\bigg)^{\rho}-\alpha}\right]^{\frac{1}{\rho}} \tag{2.1.0} $$

This analytic solution is available via the steady_state attribute.


In [ ]:
# check the docstring...
ces_model.steady_state?

In [ ]:
ces_model.steady_state

2.2 Numerical methods

Although it is trivial to derive an analytic expression for the long-run equilibrium of the Solow model for most intensive production functions, the Solow model serves as a good illustrative case for various numerical methods for solving non-linear equations.

The solow.Model.find_steady_state method provides a simple interface to the various 1D root finding routines available in scipy.optimize and uses them to solve the non-linear equation 2.0.1. To see the list of currently supported methods, check out the docstring for the Model.find_steady_state method...


In [ ]:
solow.Model.find_steady_state?

Example usage

Guessing that the true steady state value lies somewhere between 1e-6 and 1e6, compute the steady state value of capital stock (per unit effective labor) using the bisection method.


In [ ]:
k_star, result = ces_model.find_steady_state(1e-6, 1e6, method='bisect', full_output=True)

We can display the value and confirm that the algorithm did indeed converge as follows.


In [ ]:
print("The steady-state value is {}".format(k_star))
print("Did the bisection algorithm coverge? {}".format(result.converged))

2.1.1 Comparing the various methods

The various methods, for the most part, are equally accurate...


In [ ]:
valid_methods = ['brenth', 'brentq', 'ridder', 'bisect']

for method in valid_methods:
    actual_ss = ces_model.find_steady_state(1e-6, 1e6, method=method)
    expected_ss = ces_model.steady_state

    print("Steady state value computed using {} is {}".format(method, actual_ss)) 
    print("Absolute error in is {}\n".format(abs(actual_ss - expected_ss)))

...however the brentq and brenth routines are generally more efficient.


In [ ]:
valid_methods = ['brenth', 'brentq', 'ridder', 'bisect']

for method in valid_methods:
    print("Profiling results using {}:".format(method)) 
    %timeit -n 1 -r 3 ces_model.find_steady_state(1e-6, 1e6, method=method)
    print("")

While the bisection method tends to be slow (relative to other methods), so long as the user brackets the true steady state value, it is guranteed to converge. Using numerical methods to solve for the steady state of the Solow model illustrates a trade-off between robustness (i.e., guaranteed convergence) and computational efficiency (i.e., speed) that is commonly encountered in numerical work.


In [ ]: